﻿/*
	flad : Copyright 2010 Dale J Williams

	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/
package lads.flad.display {
	
	import lads.flad.interfaces.ILoadable;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	
	/**
	 * BitmapWidget: Designed to handle automatic cropping and resizing
	 * of bitmaps, to constrict with frames.
	 * @author Dale J Williams
	 * @version 1.2
	 */
	public class BitmapWidget extends Widget implements ILoadable {
		
		private var _url		:String;
		private var _bitmapData	:BitmapData;
		private var _cropping	:Boolean;
		private var _smoothing	:Boolean;
		private var _loadPC		:Number;
		private var _loaded		:Boolean;
		private var _matrix		:Matrix;
		
		public function BitmapWidget($url:String = null) {
			_url = $url;
			init();
		}
		
		private function init():void {
			smoothing = true;
			cropping = true;
			_loadPC = 0;
			_matrix = new Matrix();
			if (_url) load();
			onDraw = draw;
		}
		
		public function load($url:String=null):void {
			if ($url) _url = $url;
			_loadPC = 0;
			_loaded = false;
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadProgress);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);
			loader.load(new URLRequest(_url));
		}
		
		private function loadProgress(e:ProgressEvent):void {
			_loadPC = e.bytesLoaded / e.bytesTotal;
		}
		
		private function loadComplete(e:Event):void {
			e.target.removeEventListener(Event.COMPLETE, loadComplete);
			e.target.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
			e.target.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
			if (_bitmapData) _bitmapData.dispose();
			_bitmapData = BitmapData(e.target.content.bitmapData);
			_loadPC = 1;
			_loaded = true;
			draw();
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		private function loadError(e:Event):void {
			e.target.removeEventListener(Event.COMPLETE, loadComplete);
			e.target.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
			e.target.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
			throw new Error("BitmapWidget error loading " + _url);
		}
		
		private function draw():void {
			if (!_bitmapData) return;
			if (_bitmapData.width < 1 || _bitmapData.height < 1) return;
			var byWidth:Boolean, rX:Number, rY:Number, oX:Number, oY:Number, pX:Number, pY:Number;
			
			rX = _width / _bitmapData.width;
			rY = _height / _bitmapData.height;		
			
			byWidth = rX < rY != _cropping;
			
			_matrix.a = byWidth ? rX : rY;
			_matrix.d = !byWidth ? rY : rX;
			
			oX = (_width - _bitmapData.width * _matrix.a) * 0.5;
			oY = (_height - _bitmapData.height * _matrix.d) * 0.5;
			
			_matrix.tx = !byWidth ? oX : 0;
			_matrix.ty = byWidth ? oY : 0;
			
			pX = _cropping ? 0 : oX; 
			pY = _cropping ? 0 : oY;
			
			graphics.clear();
			graphics.beginBitmapFill(_bitmapData, _matrix, true, _smoothing);
			graphics.drawRect(pX, pY, _width-pX*2, _height-pY*2);
			graphics.endFill();
		}
				
		public function get cropping():Boolean { return _cropping; }		
		public function set cropping(value:Boolean):void {
			_cropping = value;
			drawNextRender();
		}
		
		public function get smoothing():Boolean { return _smoothing; }		
		public function set smoothing(value:Boolean):void {
			_smoothing = value;
			drawNextRender();
		}
		
		public function get loadPercent():Number { return _loadPC; }
		
		public function get loadCompleted():Boolean { return _loaded; }
		
		public function get bitmapData():BitmapData { return _bitmapData; }		
		public function set bitmapData(value:BitmapData):void {
			_bitmapData = value;
			draw();
		}
		
		public function get url():String { return _url; }		
		public function set url(value:String):void {
			_url = value;
		}
		
	}

}